Um erro muito comum de modelagem de banco de dados ocorre ao se usar campos multivalorados.
Para exemplificar, vamos usar um sistema de cadastro onde as pessoas informam as linguagens de programação que conhecem.
Muitas pessoas criariam uma tabela no banco de dados com esta estrutura:
Tabela pessoas
ID Nome Linguagens 1 Gisele PHP,Java,Shell Script,Ruby 2 Maria C,C++,Shell Script,Lua 3 Ana PHP,Ruby,Lua
Essa estrutura não é aconselhável. Imagine se precisar buscar pelas pessoas que conhecem PHP. Você terá de fazer uma consulta assim (para MySQL):
SELECT id, pessoa FROM pessoas WHERE linguagens LIKE '%PHP%'; |
Aparentemente não é complicado, mas, para o processador, é pior fazer um Like que fazer uma comparação de igualdade.
Situação pior é a ação de editar o campo das linguagens. É necessário editar a string.
A solução é simples: criar relacionamento entre tabelas.
Criaremos trÊs tabelas: uma conterá os nomes das pessoas; outra, os nomes das linguagens; e, finalmente, a tabela que relaicionará as duas anteriores, associando a cada pessoa uma ou mais linguagens.
Tabela pessoas
ID Nome 1 Ana 2 Gisele 3 Maria
Tabela linguagens
ID Nome 1 PHP 2 C 3 Java 4 Ruby
Tabela pessoas_linguagens
ID_PESSOA ID_LINGUAGEM 1 1 1 2 2 2 2 3 3 1 3 2 3 3
Esta última tabela é a responsável por relacionar cada pessoa às linguagens que conhece. Note que o ID da pessoa pode aparecer em quantos registros forem necessários, ou seja, nessa tabela não há chave primária.
Segundo a tabela, a pessoa 1 (Ana) conhece as linguagens 1 e 2 (PHP e C). A pessoa 2 (Gisele) conhece as linguagens 2 e 3 (C e Java). A pessoa 3 (Maria) conhece as linguagens 1, 2 e 3 (PHP, C e Java).
Com uma estrutura assim, é bem mais fácil editar valores, removê-los ou buscar pessoas que detêm determinado conhecimento.
Darei um exemplo, para MySQL, de como fazer um SELECT para mostrar as linguagens que cada pessoa conhece.
Usaremos esta estrutura de tabelas:
### Tabela com os nomes das pessoas CREATE TABLE pessoas( id SMALLINT(5) UNSIGNED NOT NULL AUTO_INCREMENT, nome VARCHAR(20) NOT NULL, PRIMARY KEY (id) ) TYPE InnoDB DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; ### Tabela com AS linguagens CREATE TABLE linguagens( id SMALLINT(5) UNSIGNED NOT NULL AUTO_INCREMENT, nome VARCHAR(20) NOT NULL, PRIMARY KEY (id) ) TYPE InnoDB DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; ### Tabela para relacionar AS duas anteriores CREATE TABLE pessoas_linguagens( id_pessoa SMALLINT(5) UNSIGNED NOT NULL, id_linguagem SMALLINT(5) UNSIGNED NOT NULL ) TYPE InnoDB DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; INSERT INTO pessoas VALUES (1, 'João'), (2, 'Maria'), (3, 'José'), (4, 'Gisele'), (5, 'Ana'); INSERT INTO linguagens VALUES (1, 'PHP'), (2, 'Java'), (3, 'Lua'), (4, 'C'), (5, 'C++'), (6, 'Shell Script'), (7, 'Ruby'); INSERT INTO pessoas_linguagens VALUES (1, 1), (1, 2), (1, 3), (1, 4), (1, 6), (2, 1), (2, 3), (2, 6), (2, 7), (3, 1), (3, 2), (3, 4), (3, 5); |
A consulta SQL:
SELECT p.nome AS pessoa , l.nome AS linguagem FROM pessoas AS p JOIN pessoas_linguagens AS pl ON pl.id_pessoa = p.id JOIN linguagens AS l ON l.id = pl.id_linguagem ORDER BY p.nome ASC; |
Da para melhorar essa estrutura, fazendo, por exemplo, integridade referencial (chave estrangeira). Mas não abordarei esse tema neste post.
No meu Curso ULTIMATE PHP eu falo mais sobre banco de dados e Normalização. No capítulo final, onde montaremos uma aplicação prática, mostro como usar essa modelagem, com um exemplo passo-a-passo, usando MySQL e PDO. Clique aqui e conheça o Curso ULTIMATE PHP.
No meu Guia Gratuito de 15 Dicas e Boas Práticas de PHP falo sobre bancos de dados e outros pontos fundamentais para criar scripts PHP eficientes e com bom desempenho. Clique aqui para baixar o guia gratuito agora mesmo.
Essa e inúmeras outras dicas e técnicas eu abordo com mais detalhes no meu Curso ULTIMATE PHP. Estude PHP desde o básico, de forma 100% prática. Aprenda como se tornar um excelente programador, reconhecido e valorizado. Clique Aqui e Conheça o Curso Agora Mesmo!
Roberto Beraldo
Latest posts by Roberto Beraldo (see all)
- Não Tenha Preguiça de Ler! - 25/04/2016
- Como Atualizar Scripts PHP de MySQL Para MySQLi - 29/10/2015
- Como usar PDO com banco de dados MySQL - 10/09/2015